const child_process = require("child_process");
const { caches, isObject, getUid } = require("./util");
const kill = require('tree-kill');
class Fork {
  constructor(opt) {
    this.fork = child_process.fork(opt.path, opt.args, opt.option);
    this.fork.on("exit", () => {
      kill(this.fork.pid)
      this.fork= null
    });
    this.fork.on("error", () => {
      kill(this.fork.pid)
    this.fork= null
    });
  }
  /**
   * 发送信息 - father
   * @param {*} data
   * @param {*} callback
   */
  sendMsg(data) {
    return new Promise((resolve) => {
      if (!isObject(data)) throw Error(`${data}不是object`);
      const uid = getUid();
      caches.set(uid, resolve);
      this.fork.on("message", (data = {}) => {
        const obj = JSON.parse(data);
        if (obj.status == 3) {
          obj.status = 4;
        } else {
          return;
        }
        if (caches.has(obj.id) && obj.status == 4) {
          // 结束会话
          caches.get(obj.id)(obj.msg);
          caches.delete(obj.id);
        }
      });

      // status 1主动发送，2接收到主动发送，3响应主动，4主动接收到响应
      this.fork.send(JSON.stringify({ id: uid, msg: data, status: 1 }));
    });
  }
  /**
   * 监听信息 - father
   * @param {*} callback
   */
  onMsg(callback) {
    this.fork.on("message", (data = {}) => {
      const obj = JSON.parse(data);
      if (obj.status == 1) obj.status = 2;
      const _this = this
      function res(e) {
        if (!isObject(e)) throw Error(`${e}不是object`);
        if (obj.status == 2) {
          obj.status = 3;
        } else {
          // console.log('应答任务已结束',obj)
          return;
        }
        _this.fork.send(
          JSON.stringify({ id: obj.id, msg: e, status: obj.status })
        );
      }
      callback(obj.msg, res);
    });
  }
  close() {
    kill(this.fork.pid)
    this.fork= null
  }
}

module.exports = Fork;
